Revision: pymad--main--0--patch-2
Archive: jaq@spacepants.org--2004
Creator: Jamie Wilkinson <jaq@spacepants.org>
Date: Tue Aug 24 12:28:52 EST 2004
Standard-date: 2004-08-24 02:28:52 GMT
Modified-files: THANKS src/pymadfile.c
New-patches: jaq@spacepants.org--2004/pymad--main--0--patch-2
Summary: clear exception after failure
Keywords: 

Brian Warner sent in a brilliant patch that cleans up when an AttributeError
occurs with StringIO files:

 ---
Date: Thu, 15 Jul 2004 15:04:27 -0700 (PDT)
From: Brian Warner <warner@lothar.com>
Subject: [PATCH] pymad exception handling

I ran into a problem when passing a file-like object to the MadFile()
constructor. It seems that py_madfile_new() calls calc_total_time(), which
attempts to get the data source's .fileno and use it to do an fstat(). If the
file-like object you pass in is not actually a file (say, a StringIO
instead), that attribute lookup will fail, and calc_total_time() fails fairly
gracefully, simply admitting that it doesn't know how long the file is.

However, the failed lookup leaves an AttributeError exception lying around.
This exception will be caught the next time any C extension is called which
does proper error-handling, which includes a number of built-in python
functions, like a 'for' loop. This results in random failures due to
AttributeErrors, sometimes in very weird places. A simple test case is here:
(tested against debian/unstable, with pymad-0.5.1-1):

#! /usr/bin/python
import mad, StringIO

data = StringIO.StringIO(open("foo.mp3","r").read())
m = mad.MadFile(data)
print "MadFile returned"
for x in (1,2): pass
print "got here"


In the failing case, the "for" statement fails with an AttributeError
exception.

The fix is easy, we just have to clear the error in the C code after it has
been noticed. A one-liner patch is attached. Hope you find it useful.


